package org.ruiyichen.guizhou.agr.ui.mineview;

import android.app.TimePickerDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.TimePicker;

import org.ruiyichen.guizhou.agr.R;
import org.ruiyichen.guizhou.agr.ui.listener.OnRecyclerItemClick;
import org.ruiyichen.guizhou.agr.utils.ListUtil;
import org.ruiyichen.guizhou.agr.utils.StrUtil;

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;

import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

/**
 * 时间段选择器
 */
public class TimePeriodSelector extends LinearLayout {

    private static final DecimalFormat df = new DecimalFormat("00");
    private final int MAX_SIZE = 6;

    RecyclerView rvSelectTime;
    TextView tvAddTimePeriod;
    TimePeriodSelectorRecyclerAdapter adapter;

    public TimePeriodSelector(Context context) {
        super(context);
        init();
    }

    public TimePeriodSelector(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public TimePeriodSelector(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        LayoutInflater.from(getContext()).inflate(R.layout.df_view_time_period_selector, this);
        rvSelectTime = findViewById(R.id.rv_select_time);
        tvAddTimePeriod = findViewById(R.id.tv_add_time_period);
        rvSelectTime.setNestedScrollingEnabled(false);
        LinearLayoutManager layoutManager = new LinearLayoutManager(getContext());
        layoutManager.setOrientation(RecyclerView.VERTICAL);
        rvSelectTime.setLayoutManager(layoutManager);
        rvSelectTime.setAdapter(adapter = new TimePeriodSelectorRecyclerAdapter(getContext()));
        adapter.setOnRecyclerItemClick(new OnRecyclerItemClick() {
            @Override
            public void onItemClick(final View view, final int position) {
                if (view.getId() == R.id.tv_time_period_start) {
                    //开始
                    //实例化时间选择器
                    //参数1：上下文对象
                    //参数2：监听事件
                    //参数3：初始化小时
                    //参数4：初始化分钟
                    //参数5：是否24小时制
                    new TimePickerDialog(getContext(), new TimePickerDialog.OnTimeSetListener() {
                        //实现监听方法
                        @Override
                        public void onTimeSet(TimePicker timePicker, int hour, int minute) {
                            //设置文本显示内容
                            //tv1.setText("当前时间：" + Year + "年" + month + "月" + day + "日   " + hour + ":" + minute);
                            if (adapter.verifyDataLegal(position, true, hour, minute)) {
                                PeriodSelector periodSelector = adapter.getModelByPos(position);
                                if (periodSelector != null && periodSelector.mustBeforeEndTime
                                        (hour, minute)) {
                                    periodSelector.setStartTime(hour, minute);
                                    adapter.notifyItemChanged(position);
                                } else {
                                    BToast.getInstance().show("开始时间必须小于结束时间~");
                                }
                            } else {
                                BToast.getInstance().show("该时间段已经存在，请重新选择~");
                            }
                        }
                    }, 0, 0, true).show();
                } else if (view.getId() == R.id.tv_time_period_end) {
                    //结束
                    new TimePickerDialog(getContext(), new TimePickerDialog.OnTimeSetListener() {
                        //实现监听方法
                        @Override
                        public void onTimeSet(TimePicker timePicker, int hour, int minute) {
                            //设置文本显示内容
                            //tv1.setText("当前时间：" + Year + "年" + month + "月" + day + "日   " + hour + ":" + minute);
                            if (adapter.verifyDataLegal(position, false, hour, minute)) {
                                PeriodSelector periodSelector = adapter.getModelByPos(position);
                                if (periodSelector != null && periodSelector.mustAfterStartTime(
                                        hour, minute)) {
                                    periodSelector.setEndTime(hour, minute);
                                    adapter.notifyItemChanged(position);
                                } else {
                                    BToast.getInstance().show("结束时间必须大于结束时间~");
                                }
                            } else {
                                BToast.getInstance().show("该时间段已经存在，请重新选择~");
                            }
                        }
                    }, 0, 0, true).show();
                } else {
                    //删除
                    CustomDialog dialog = new CustomDialog.Builder(getContext(), CustomDialog.Style
                            .MULTI_TIPS)
                            .setTitle("温馨提示")
                            .setMessage("是否删除该时间段？")
                            .setNegativeButton("确定", new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialog, int which) {
                                    dialog.dismiss();
                                    adapter.deleteTimePeriod(position);
                                }
                            })
                            .setPositiveButton("取消", new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialog, int which) {
                                    dialog.dismiss();
                                }
                            }).setTitle("提示")
                            .create();
                    dialog.show();
                }
            }
        });
        tvAddTimePeriod.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View view) {
                adapter.addTimePeriod();
            }
        });
    }

    public boolean canSubmit() {
        return adapter.canSubmit();
    }

    public int getSelectTimeValue() {
        return adapter.getSelectTimeValue();
    }

    public String getSelectTimePeriodStr() {
        return adapter.getSelectTimePeriodStr();
    }

    class TimePeriodSelectorRecyclerAdapter extends RecyclerView.Adapter<TimePeriodSelectorRecyclerAdapter.BViewHolder> {

        private List<PeriodSelector> mDatas = new ArrayList<>(MAX_SIZE);
        private Context mContext;
        private LayoutInflater inflater;

        private OnRecyclerItemClick onRecyclerItemClick;


        public TimePeriodSelectorRecyclerAdapter(Context context) {
            this.mContext = context;
            inflater = LayoutInflater.from(mContext);
        }

        public void setmDatas(List<PeriodSelector> mDatas) {
            mDatas.clear();
            if (ListUtil.isNotEmpty(mDatas)) {
                this.mDatas = mDatas;
            }
            notifyDataSetChanged();
        }

        public void addTimePeriod() {
            if (getItemCount() < MAX_SIZE) {
                mDatas.add(new PeriodSelector());
                notifyDataSetChanged();
            } else {
                BToast.getInstance().show("已经达到最大添加数，无法添加~");
            }
        }

        public void deleteTimePeriod(int position) {
            mDatas.remove(position);
            notifyDataSetChanged();
        }

        public void setOnRecyclerItemClick(OnRecyclerItemClick onRecyclerItemClick) {
            this.onRecyclerItemClick = onRecyclerItemClick;
        }

        //填充onCreateViewHolder方法返回的holder中的控件
        @Override
        public void onBindViewHolder(BViewHolder holder, final int position) {
            holder.tvTimePeriodStart.setText(mDatas.get(position).startTimePeriod2Str());
            holder.tvTimePeriodEnd.setText(mDatas.get(position).endTimePeriod2Str());
        }

        //重写onCreateViewHolder方法，返回一个自定义的ViewHolder
        @Override
        public BViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            View view = inflater.inflate(R.layout.df_item_time_period_selector, parent, false);
            BViewHolder holder = new BViewHolder(view);
            return holder;
        }

        public boolean isLastPosition(RecyclerView.ViewHolder holder) {
            int position = holder.getLayoutPosition();
            return position == mDatas.size() - 1;
        }

        @Override
        public int getItemCount() {
            if (mDatas == null) return 0;
            return mDatas.size();
        }

        public PeriodSelector getModelByPos(int position) {
            if (position >= 0 && position < getItemCount()) {
                return mDatas.get(position);
            }
            return null;
        }

        public boolean verifyDataLegal(int position, boolean isStart, int hour, int minute) {
            if (ListUtil.isEmpty(mDatas)) {
                return true;
            }
            for (int i = 0; i < mDatas.size(); i++) {
                if (i == position) {
                    //自己不验证
                    continue;
                }
                //自己所在行必须屏蔽 包含验证
                if (mDatas.get(i).containTheTime(hour, minute)) {
                    return false;
                }
                //被包含验证
                if (isStart) {
                    //开始时间
                    TimePeriod endTimePeriod = mDatas.get(position).getEndTimePeriod();
                    if (endTimePeriod == null || endTimePeriod.hasNotSelectTime()) {
                        //时间未选择 下一个
                        continue;
                    }
                    //当初选择时间构成的时间段是否被包含
                    return !mDatas.get(i).coverContainTheTime(isStart, hour, minute, endTimePeriod);
                } else {
                    //结束时间
                    TimePeriod startTimePeriod = mDatas.get(position).getStartTimePeriod();
                    if (startTimePeriod == null || startTimePeriod.hasNotSelectTime()) {
                        //时间未选择 下一个
                        continue;
                    }
                    //当初选择时间构成的时间段是否被包含
                    return !mDatas.get(i).coverContainTheTime(isStart, hour, minute,
                            startTimePeriod);
                }
            }
            return true;
        }

        public boolean canSubmit() {
            if (ListUtil.isEmpty(mDatas)) {
                return false;
            }
            for (int i = 0; i < mDatas.size(); i++) {
                if (mDatas.get(i) != null &&
                        //起始时间选择
                        mDatas.get(i).periodSelector[0] != null && !mDatas.get(i).periodSelector[0]
                        .hasNotSelectTime() &&
                        //结束时间选择
                        mDatas.get(i).periodSelector[1] != null && !mDatas.get(i).periodSelector[1]
                        .hasNotSelectTime()
                        ) {
                } else {
                    return false;
                }
            }
            return true;
        }

        public int getSelectTimeValue() {
            if (ListUtil.isNotEmpty(mDatas)) {
                int totalTime = 0;
                for (int i = 0; i < mDatas.size(); i++) {
                    if (mDatas.get(i) != null &&
                            //起始时间
                            mDatas.get(i).getStartTimePeriod() != null && !mDatas.get(i)
                            .getStartTimePeriod().hasNotSelectTime() &&
                            //结束时间
                            mDatas.get(i).getEndTimePeriod() != null && !mDatas.get(i)
                            .getEndTimePeriod().hasNotSelectTime() &&
                            //结束时间必须大于开始时间
                            mDatas.get(i).getEndTimePeriod().time2RealValue() > mDatas.get(i)
                                    .getStartTimePeriod().time2RealValue()
                            ) {
                        totalTime += mDatas.get(i).getEndTimePeriod().time2RealValue() - mDatas
                                .get(i)
                                .getStartTimePeriod().time2RealValue();
                    }
                }
                return totalTime;
            }
            return 0;
        }

        public String getSelectTimePeriodStr() {
            if (ListUtil.isNotEmpty(mDatas)) {
                StringBuffer sb = new StringBuffer();
                for (int i = 0; i < mDatas.size(); i++) {
                    if (mDatas.get(i) != null &&
                            //起始时间
                            mDatas.get(i).getStartTimePeriod() != null && !mDatas.get(i)
                            .getStartTimePeriod().hasNotSelectTime() &&
                            //结束时间
                            mDatas.get(i).getEndTimePeriod() != null && !mDatas.get(i)
                            .getEndTimePeriod().hasNotSelectTime() &&
                            //结束时间必须大于开始时间
                            mDatas.get(i).getEndTimePeriod().time2RealValue() > mDatas.get(i)
                                    .getStartTimePeriod().time2RealValue()
                            ) {
                        if (StrUtil.isNotEmpty(sb.toString())) {
                            sb.append(",");
                        }
                        sb.append(
                                //开始时间
                                mDatas.get(i).getStartTimePeriod().hour2Str()).append(":").append
                                (mDatas
                                        .get(i).getStartTimePeriod().minute2Str()).append(":00").append("-")
                                //结束时间
                                .append(mDatas.get(i).getEndTimePeriod().hour2Str()).append(":").append
                                (mDatas
                                        .get(i).getEndTimePeriod().minute2Str()).append(":00");
                    }
                }
                return sb.toString();
            }
            return "";
        }


        /**
         * 协办员
         */
        class BViewHolder extends RecyclerView.ViewHolder {

            TextView
                    tvTimePeriodStart,
                    tvTimePeriodEnd, tvTimePeriodDelete;

            public BViewHolder(final View view) {
                super(view);
                tvTimePeriodStart = view.findViewById(R.id.tv_time_period_start);
                tvTimePeriodEnd = view.findViewById(R.id.tv_time_period_end);
                tvTimePeriodDelete = view.findViewById(R.id.tv_time_period_delete);
                tvTimePeriodStart.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        if (onRecyclerItemClick != null) {
                            onRecyclerItemClick.onItemClick(v, getLayoutPosition());
                        }
                    }
                });
                tvTimePeriodEnd.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        if (onRecyclerItemClick != null) {
                            onRecyclerItemClick.onItemClick(v, getLayoutPosition());
                        }
                    }
                });
                tvTimePeriodDelete.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        if (onRecyclerItemClick != null) {
                            onRecyclerItemClick.onItemClick(v, getLayoutPosition());
                        }
                    }
                });
            }
        }
    }

    public class PeriodSelector {

        public final TimePeriod[] periodSelector = new TimePeriod[2];

        public PeriodSelector() {
        }

        public PeriodSelector setStartTime(TimePeriod startTime) {
            periodSelector[0] = startTime;
            return this;
        }

        public PeriodSelector setEndTime(TimePeriod endTime) {
            periodSelector[1] = endTime;
            return this;
        }


        public TimePeriod getStartTimePeriod() {
            return periodSelector[0];
        }

        public TimePeriod getEndTimePeriod() {
            return periodSelector[1];
        }

        public String startTimePeriod2Str() {
            if (periodSelector[0] == null || periodSelector[0].hasNotSelectTime()) {
                return "请选择";
            }
            return periodSelector[0].hour2Str() + ":" + periodSelector[0].minute2Str();
        }

        public String endTimePeriod2Str() {
            if (periodSelector[1] == null || periodSelector[1].hasNotSelectTime()) {
                return "请选择";
            }
            return periodSelector[1].hour2Str() + ":" + periodSelector[1].minute2Str();
        }

        public void setStartTime(int hour, int minute) {
            if (periodSelector[0] == null) {
                periodSelector[0] = new TimePeriod(hour, minute);
                return;
            }
            periodSelector[0].hour = hour;
            periodSelector[0].minute = minute;
        }

        public void setEndTime(int hour, int minute) {
            if (periodSelector[1] == null) {
                periodSelector[1] = new TimePeriod(hour, minute);
                return;
            }
            periodSelector[1].hour = hour;
            periodSelector[1].minute = minute;
        }

        public boolean containTheTime(int hour, int minute) {
            if (periodSelector[0] == null || periodSelector[0].hasNotSelectTime()
                    || periodSelector[1] == null || periodSelector[1].hasNotSelectTime()) {
                return false;
            }
            int realValue = hour * 60 + minute;
            if (realValue >= periodSelector[0].time2RealValue() && realValue <= periodSelector[1]
                    .time2RealValue()) {
                return true;
            }
            return false;
        }

        public boolean mustBeforeEndTime(int hour, int minute) {
            if (periodSelector[1] != null &&
                    //选择过时间
                    !periodSelector[1].hasNotSelectTime()) {
                return (hour * 60 + minute) < periodSelector[1].time2RealValue();
            }
            return true;
        }

        public boolean mustAfterStartTime(int hour, int minute) {
            if (periodSelector[0] != null &&
                    //选择过时间
                    !periodSelector[0].hasNotSelectTime()) {
                return (hour * 60 + minute) > periodSelector[0].time2RealValue();
            }
            return true;
        }

        public boolean coverContainTheTime(boolean isStart, int hour, int minute, TimePeriod
                curTimePeriod) {
            TimePeriod startTimePeriod = periodSelector[0];
            TimePeriod endTimePeriod = periodSelector[1];
            //时间未选择
            if ((startTimePeriod == null || startTimePeriod.hasNotSelectTime()) &&
                    (endTimePeriod == null || endTimePeriod.hasNotSelectTime())) {
                return false;
            }
            if (isStart) {
                return (startTimePeriod != null && startTimePeriod.time2RealValue() >= (hour * 60
                        + minute)
                        && startTimePeriod.time2RealValue() <= curTimePeriod.time2RealValue()) ||
                        //结束时间验证
                        (endTimePeriod != null && endTimePeriod.time2RealValue() >= (hour * 60 +
                                minute)
                                && endTimePeriod.time2RealValue() <= curTimePeriod.time2RealValue
                                ());
            } else {
                //结束
                return (startTimePeriod != null && startTimePeriod.time2RealValue() <= (hour * 60
                        + minute)
                        && startTimePeriod.time2RealValue() >= curTimePeriod.time2RealValue()) ||
                        //结束时间验证
                        (endTimePeriod != null && endTimePeriod.time2RealValue() <= (hour * 60 +
                                minute)
                                && endTimePeriod.time2RealValue() >= curTimePeriod.time2RealValue
                                ());
            }
        }
    }

    /**
     * 时间选择器对象
     */
    public class TimePeriod {

        public int hour;
        public int minute;

        public TimePeriod() {
            this.hour = -1;
            this.minute = -1;
        }

        public TimePeriod(int hour, int minute) {
            this.hour = hour;
            this.minute = minute;
        }

        public String hour2Str() {
            if (hasNotSelectHour()) {
                return "请选择";
            }
            return df.format(hour);
        }

        public String minute2Str() {
            if (hasNotSelectMinute()) {
                return "请选择";
            }
            return df.format(minute);
        }

        public int time2RealValue() {
            return hour * 60 + minute;
        }

        public boolean hasNotSelectTime() {
            return hasNotSelectHour() || hasNotSelectMinute();
        }

        public boolean hasNotSelectHour() {
            return hour == -1;
        }

        public boolean hasNotSelectMinute() {
            return minute == -1;
        }

    }
}
